package be.dch.guice.modules;

import org.apache.log4j.Logger;

import be.dch.guice.utils.AbstractModuleUtil;
import be.dch.guice.xsd.GuiceConfiguration;
import be.dch.guice.xsd.MultiBindingType;

import com.google.inject.AbstractModule;
import com.google.inject.multibindings.Multibinder;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class MultiBindingConfig implements ExtraConfig {

    private static final Logger LOG = Logger.getLogger(MultiBindingConfig.class);

    /*
     * (non-Javadoc)
     * 
     * @see
     * be.dch.guice.modules.ExtraConfig#process(be.dch.guice.xsd.GuiceConfiguration
     * , be.dch.guice.modules.ExternalConfigModule)
     */
    public void process(final GuiceConfiguration config, final AbstractModule module) {
	final AbstractModuleUtil util = new AbstractModuleUtil(module);
	MultiBindingConfig.LOG.debug(config.getConfigName() + " ## configuring all multi bindings");
	for (final MultiBindingType multi : config.getMultiBinding()) {
	    this.processMultiBinding(config, multi, util);
	}
    }

    private void processMultiBinding(final GuiceConfiguration config, final MultiBindingType multi, final AbstractModuleUtil module) {

	// TODO add logging
	try {

	    final Class iface = Class.forName(multi.getInterface());
	    final Multibinder multibinder = Multibinder.newSetBinder(module.binder(), iface);
	    for (final String clazz : multi.getImplementation()) {
		final Class impl = Class.forName(clazz);
		if (!impl.isInterface()) {
		    multibinder.addBinding().to(impl);
		}
	    }

	} catch (final ClassNotFoundException e) {
	    module.addError(e);
	    MultiBindingConfig.LOG.error(e);
	}
    }

}
